//============================================================================
// Copyright (C) 2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include <memory.h>
#include <stdio.h>
#include "VxCommon.h"
#include "VxStringUtil.h"
#include "vx_debug.h"

//============================================================================
PluginPermission::PluginPermission()
	: m_u64Permissions(0)
{
	// empty
}

//============================================================================
bool PluginPermission::isPluginEnabled( EPluginType ePlugin )		
{ 
	return (eFriendStateIgnore == getPluginPermission(ePlugin))?0:1; 
}

//============================================================================
//! get type of permission user has set for givin plugin
EFriendState PluginPermission::getPluginPermission( EPluginType ePluginType ) 
{ 
	if(( ePluginType > 0 ) && ( ePluginType < eMaxPluginType ) )
	{
		return  (EFriendState)((m_u64Permissions >> ((ePluginType-1)*4))&0xf); 
	}
	return eFriendStateIgnore;
}

//============================================================================
//! set type of permission user has set for givin plugin
void PluginPermission::setPluginPermission( EPluginType ePluginType, EFriendState eFriendState ) 
{ 
	if(( ePluginType > 0 ) && ( ePluginType < eMaxPluginType ) )
	{
		int iShift = ((ePluginType-1)*4);
		m_u64Permissions &= ~(0xf << iShift); 
		m_u64Permissions |= (eFriendState << iShift); 
	}
}

//============================================================================
//! set all permissions
void PluginPermission::setPluginPermissions( U64 u64Permissions )		
{ 
	m_u64Permissions = u64Permissions; 
} 

//============================================================================
//=== constructor ===//
VxNetIdent::VxNetIdent()
	: m_u32TimeTcpLastContact(0)
	, m_u32TruthCnt(0)
	, m_u32DareCnt(0)
	, m_u32RejectedCnt(0)
	, m_u32AvatarTimeLastChange(0)
	, m_u16AvatarId(0)							
	, m_u16AppVersion(APP_VERSION)	
	, m_u16PingTimeMs(0)
	, m_u16NetRes1(0)
	, m_u32NetRes2(0)							
	, m_u32NetRes3(0)
	, m_u32NetRes4(0)							
{
	memset( m_as8OnlineDesc, 0, sizeof( m_as8OnlineDesc ) );
}

//============================================================================
void VxNetIdent::setDareCount( U32 dareCnt )
{
	m_u32DareCnt = dareCnt;
}

//============================================================================
U32	VxNetIdent::getDareCount()
{
	return m_u32DareCnt;
}

//============================================================================
void VxNetIdent::setRejectedCount( U32 rejectedCnt )
{
	m_u32RejectedCnt = rejectedCnt;
}

//============================================================================
U32	VxNetIdent::getRejectedCount()
{
	return m_u32RejectedCnt;
}

//============================================================================
void VxNetIdent::setTruthCount( U32 truthCnt )
{
	m_u32TruthCnt = truthCnt;
}

//============================================================================
U32	VxNetIdent::getTruthCount()
{
	return m_u32TruthCnt;
}

//============================================================================
//! return users online description
char *	VxNetIdent::getOnlineDescription( void )					
{	
	return m_as8OnlineDesc; 
}

//============================================================================
//! return users online description as string
void	VxNetIdent::getOnlineDescription( std::string& strRetDesc )	
{ 
	strRetDesc = m_as8OnlineDesc; 
}

//============================================================================
//! set users online description
void 	VxNetIdent::setOnlineDescription( const char * pUserDesc )	
{ 
	VxSafeStrCopy( m_as8OnlineDesc, pUserDesc, sizeof( m_as8OnlineDesc )); 
}

//============================================================================
EPluginAccessState	VxNetIdent::getPluginAccessState( EPluginType ePluginType )
{
	return getPluginAccessState( ePluginType, getHisFriendshipToMe() );
}

//============================================================================
EPluginAccessState	VxNetIdent::getPluginAccessState( EPluginType ePluginType, EFriendState eHisPermissionToMe )
{
	if( eFriendStateIgnore == eHisPermissionToMe )
	{
		return ePluginAccessIgnored;
	}
	EFriendState ePermissionLevel = this->getPluginPermission(ePluginType);
	if( eFriendStateIgnore == ePermissionLevel )
	{
		return ePluginAccessDisabled;
	}
	if( ePermissionLevel > eHisPermissionToMe )
	{
		return ePluginAccessLocked;
	}
#ifdef USE_PLUGIN_FILE_SERVER
	if( (ePluginTypeFileServer == ePluginType) && 
		(false == hasSharedFiles()) )
	{
		// no files shared
		return ePluginAccessInactive;
	}
#endif // USE_PLUGIN_FILE_SERVER
#ifdef USE_PLUGIN_FILE_SERVER
	if( (ePluginTypeCamServer == ePluginType) && 
		(false == hasSharedWebCam()) )
	{
		// no files shared
		return ePluginAccessInactive;
	}
#endif // USE_PLUGIN_FILE_SERVER
	return ePluginAccessOk;
}

//============================================================================
bool VxNetIdent::isAccessAllowed( EPluginType ePluginType )
{
	EPluginAccessState ePluginAccess = getPluginAccessState( ePluginType );
	if( ePluginAccessOk == ePluginAccess )
	{
		return true;
	}
	return false;
}

//============================================================================
//! copy operator
VxNetIdent& VxNetIdent::operator =( const VxNetIdent &a )
{
	// we can get away with memcpy because no virtual functions
	memcpy( this, &a, sizeof( VxNetIdent ) );
	return *this;
}

//============================================================================
//! dump identity
void VxNetIdent::debugDumpIdent( void )
{
	std::string strIPv4; 
	m_oDirectConnectId.getIPv4(strIPv4);
	std::string strIPv6; 
	m_oDirectConnectId.getIPv6(strIPv6);
	std::string strRelayIPv4; 
	m_oRelayConnectId.getIPv4(strRelayIPv4);
	std::string strRelayIPv6; 
	m_oRelayConnectId.getIPv6(strRelayIPv6);

	log_msg( LOG_DEBUG, "Ident %s id %s my friendship %s his friendship %s permissions 0x%llx search 0x%x ipv4 %s ipv6 %s port %d proxy flags 0x%x proxy ipv4 %s proxy ipv6 %s port %d\n",
		getOnlineName(),
		getMyOnlineId().describeOnlineId().c_str(),
		DescribeFriendState(getMyFriendshipToHim()),
		DescribeFriendState(getHisFriendshipToMe()),
		m_u64Permissions,
		m_u16SearchFlags,
		strIPv4.c_str(),
		strIPv6.c_str(),
		m_oDirectConnectId.m_u16OnlinePort,
		m_u8RelayFlags,
		strRelayIPv4.c_str(),
		strRelayIPv6.c_str(),
		m_oRelayConnectId.m_u16OnlinePort
		);
}


//============================================================================
//! describe plugin local name
const char * DescribePluginLclName( EPluginType ePluginType )
{
	switch( ePluginType )
	{
#ifdef USE_PLUGIN_WEB_SERVER
	case	ePluginTypeWebServer:	// web server plugin ( for profile web page )
		return "User Profile Web Page";
#endif // USE_PLUGIN_WEB_SERVER
#ifdef USE_PLUGIN_RELAY
	case	ePluginTypeRelay:	// web server plugin ( for profile web page )
		return "Connection Relay";
#endif // USE_PLUGIN_RELAY
#ifdef USE_PLUGIN_FILE_SERVER
	case 	ePluginTypeFileServer:	// file share plugin
		return "Shared Files";	
#endif // USE_PLUGIN_FILE_SERVER
#ifdef USE_PLUGIN_FILE_OFFER
	case 	ePluginTypeFileOffer:	// file share plugin
		return "Offer A File";
#endif // USE_PLUGIN_FILE_OFFER
#ifdef USE_PLUGIN_CAM_SERVER
	case 	ePluginTypeCamServer:	// web cam broadcast plugin
		return "Shared Video Broadcast";
#endif // USE_PLUGIN_CAM_SERVER
#ifdef USE_PLUGIN_INST_MSG
	case 	ePluginTypeInstMsg:	// instant message p2p plugin
		return "Instant Message";
#endif // USE_PLUGIN_INST_MSG
#ifdef USE_PLUGIN_VOICE_PHONE
	case 	ePluginTypeVoicePhone:	// VOIP p2p plugin
		return "VOIP Voice Phone";
#endif // USE_PLUGIN_VOICE_PHONE
#ifdef USE_PLUGIN_VIDEO_PHONE
	case 	ePluginTypeVideoPhone:	// Video phone p2p plugin
		return "Video Phone";
#endif // USE_PLUGIN_VIDEO_PHONE
#ifdef USE_PLUGIN_TRUTH_OR_DARE
	case 	ePluginTypeTruthOrDare:	// Web Cam Truth Or Dare game p2p plugin
		return "Web Cam Truth Or Dare";
#endif // USE_PLUGIN_TRUTH_OR_DARE
#ifdef USE_PLUGIN_STORY_BOARD
	case 	ePluginTypeStoryBoard:	// Web Cam Truth Or Dare game p2p plugin
		return "Story Board";
#endif // USE_PLUGIN_STORY_BOARD
	default:		
		return "Unknown Plugin";
	}
};

//============================================================================
//! report a attempt to hack or add spyware etc
RCODE VxReportHack(	VxNetIdentBase *	poContactIdent,			// users identity info ( may be null if not known then use ipAddress )
					U32					u32HackLevel,			// 1=severe 2=medium 3=suspicious
					U32					u32IpAddr,				// ip address if identity not known
					const char *		pDescription, ... )		// description of hack attempt
{
	return 0;
}
